home *** CD-ROM | disk | FTP | other *** search
- /*
- Config.c -- Version 3.0
-
- Developer Technical Support Apple II Sample Code
-
- Copyright (c) 1990 by Apple Computer, Inc.
- All Rights Reserved.
-
- This file contains the routines for loading and saving
- configuration data for the sample network aware application.
- */
-
- #include <types.h> /* {CIIGSIncludes}types.h */
- #include <GSOS.h> /* {CIIGSIncludes}GSOS.h */
- #include <MiscTool.h> /* {CIIGSIncludes}MiscTool.h */
- #include <Window.h> /* {CIIGSIncludes}Window.h */
- #include "Aware.h"
-
- /*
- The string asciiTime holds the configuration data (the time
- that the configuration was last saved, or the program was
- exited). It is stored as a C-string (zero byte terminated)
- of 20 characters.
- */
- char asciiTime[21];
-
-
- /*
- This routine, c2gstr, takes a C-string and creates a GSOS
- class 1 string (i.e. a string with a leading length WORD).
- The GSOS string is a copy, and the C-string is left
- unchanged.
- */
- void c2gstr(cstr,gstr)
- char *cstr;
- GSString32 *gstr;
- {
- char *src,*dest;
-
- src = cstr;
- dest = gstr->text;
-
- while (*src) {
- *(dest++) = *(src++);
- }
-
- gstr->length = src-cstr;
- }
-
-
- /*
- loadConfig()
-
- This routine does the actual work of loading the configuration
- information from the user's configuration file into the global
- variable asciiTime. It supplies a default value of "<unknown>"
- if the configuration data cannot be read (for example, if none
- has been saved).
-
- Note the use of the "@" prefix in the pathname of the config-
- uration file. This allows each user name to have its own
- file when run from a network, or for the file to be saved
- with the application when run from a local disk. You don't
- have to have special code to access the network; the "@"
- prefix is set up automatically just before your application
- is launched.
-
- Also note the use of the requestAccess field of the class 1
- Open call (OpenGS). Since we only need to read from the file,
- that's the only access we will request. This lets several
- users (even users logged on with the same name) to load in
- the file at the same time. This is particularly important in
- classroom settings where an entire class may launch the same
- application at the same time, all trying to open the same file
- at the same time.
- */
- void loadConfig()
- {
- Word cRefNum;
- GSString32 path;
- OpenRecGS myOpenRec;
- RefNumRecGS myCloseRec;
- IORecGS myReadRec;
-
-
- /* First, put the pathname into a suitable form for the OpenGS
- call. Convert it from a C-string to a GSString. */
- c2gstr("@:Aware.Config",&path);
-
-
- /* Next, provide a suitable default value in case there is no
- configuration file, or if there is an error while trying
- to load it. The default will be overwritten if the
- configuration can be read from the file. */
- strcpy(asciiTime,"<unknown>");
-
-
- /* Fill out the OpenGS parameter list and make the call to
- open the file. */
- myOpenRec.pCount = 3; /* include requestAccess! */
- myOpenRec.pathname = &path;
- myOpenRec.requestAccess = readEnable; /* request read only */
- OpenGS(&myOpenRec); /* do the Open call */
-
-
- /* If the open succeeded, read in the data from the file. */
- if (!_toolErr) {
-
- myReadRec.pCount = 4;
- myReadRec.refNum = myOpenRec.refNum;
- myReadRec.dataBuffer = asciiTime;
- myReadRec.requestCount = 20; /* data is always 20 bytes long */
- ReadGS(&myReadRec);
- /* If the read succeeded, the default was overwritten by the
- contents of the file. Now, just put a zero byte at the
- end of the string so that it can be used as a C-string. */
- if (!_toolErr) {
- asciiTime[myReadRec.transferCount] = 0;
- }
-
- /* Close the configuration file. */
- myCloseRec.pCount = 1;
- myCloseRec.refNum = myOpenRec.refNum;
- CloseGS(&myCloseRec);
- }
- }
-
-
- /*
- saveConfig()
-
- This routine does the actual work of saving the configuration
- information to the user's configuration file from the global
- variable asciiTime.
-
- Note the use of the "@" prefix in the pathname of the config-
- uration file. This allows each user name to have its own
- file when run from a network, or for the file to be saved
- with the application when run from a local disk. You don't
- have to have special code to access the network; the "@"
- prefix is set up automatically just before your application
- is launched.
-
- Also note the use of the requestAccess field of the class 1
- Open call (OpenGS). Even though we're only going to write
- to the file, we open it for read/write. There are two
- reasons for this. First, asking for write permission
- prevents anybody else from getting either read or write
- access, so asking for both read/write doesn't change the
- access anybody else can get. Second, since we're writing
- a small amount (i.e. less than 512 bytes) at a time, the FST
- will try to buffer the contents of the file and needs read
- access to do this. If it doesn't have read access, and you
- write some bytes, set the mark ahead some bytes, and write
- some more bytes, the bytes you skipped over cannot be
- buffered, and their original contents will be lost. In our
- case, this isn't a problem since we write continuously from
- the beginning of the file.
- */
- void saveConfig()
- {
- Word cRefNum;
- GSString32 path;
- CreateRecGS myCreateRec;
- OpenRecGS myOpenRec;
- RefNumRecGS myCloseRec;
- IORecGS myWriteRec;
- int i;
-
-
- /* Update the configuration data by getting the current
- date/time from the real time clock. ReadAsciiTime
- returns 20 characters with the high bit set, so I'll
- clear the high bits and add a trailing zero byte to
- make it a C-string. */
- ReadAsciiTime(asciiTime); /* get the current date/time */
- for (i=0; i<20; i++)
- asciiTime[i] = asciiTime[i] & 0x7F; /* clear high bit of char */
- asciiTime[20] = '\0'; /* make it a C string */
-
-
- /* Put the pathname into a suitable form for the OpenGS
- call. Convert it from a C-string to a GSString. */
- c2gstr("@:Aware.Config",&path); /* convert path to GSString */
-
-
- /* Create the file in case it doesn't exist yet. If
- it does exist, this call will return an error, and
- we'll ignore it. */
- myCreateRec.pCount = 4;
- myCreateRec.pathname = &path;
- myCreateRec.access = 0xC3; /* full access, not invisible */
- myCreateRec.fileType = 4; /* storing it as a text file */
- myCreateRec.auxType = (LongWord) 0; /* record length = 0, plain ASCII */
- CreateGS(&myCreateRec); /* create the file */
-
-
- /* Note: I'm not asking for any of the file information (such
- as file type, auxtype, size, etc.) to be returned. If I did
- ask for it, and I had make changes but not see files access,
- the Open would fail (since I didn't have access to get the
- file information). If I had only make changes (I would see
- the parent folder as a "drop box"), I could still open the
- file as long as that fork is empty (this allows me to write
- to an empty file, but not to a fork somebody else has written
- into; this makes putting a file into a "drop box" a one-way
- operation). */
- myOpenRec.pCount = 3; /* include requestAccess! */
- myOpenRec.pathname = &path;
- myOpenRec.requestAccess = readEnable+writeEnable; /* request read/write */
- OpenGS(&myOpenRec); /* do the Open call */
-
-
- /* If I was able to open the file, I know I have full access
- to it, so I will write to it. If there was an error, put
- up a dialog box informing the user. */
- if (_toolErr) {
- AlertWindow(refIsResource * 2, NULL, 2L);
- } else {
-
- /* Write the data out. If there is an error, put up
- a dialog to inform the user. */
- myWriteRec.pCount = 4;
- myWriteRec.refNum = myOpenRec.refNum;
- myWriteRec.dataBuffer = asciiTime;
- myWriteRec.requestCount = 20;
- WriteGS(&myWriteRec);
- if (_toolErr) {
- AlertWindow(refIsResource * 2, NULL, 2L);
- }
-
- /* close the file */
- myCloseRec.pCount = 1;
- myCloseRec.refNum = myOpenRec.refNum;
- CloseGS(&myCloseRec);
- }
- }
-